from wxpyview.ui.core.BaseUIGenerator import *
from wxpyview.ui.core.ObjectIndexer import *

_BUILTIN_DIALOGS = ["wx:FileDialog", "wx:MessageDialog", "wx:FontDialog",
                    "wx:ColorDialog"]

class DialogUIGenerator(BaseUIGenerator):
    def __init__(self):
        self.mw_trees = []
        self.global_metawidget_index = None

    def parse(self, resource_path):
        BaseUIGenerator.parse(self, resource_path)

        dom_tree = DOM()
        dom_tree.create(resource_path)
        
        dom_tree_head = dom_tree.getRootNode()
        
        for dom_node in dom_tree_head.childNodes:
            # check valid dialog DOM
            if dom_node.nodeType != dom_node.ELEMENT_NODE: continue
            if dom_node.nodeName not in ["wx:Dialog"] + _BUILTIN_DIALOGS:
                raise "INVALID DIALOG UI DESCRIPTION"
             
            self._createMetaWidgets(dom_node)

        self._constructGlobalMetaWidgetIndex()

    def _constructGlobalMetaWidgetIndex(self):
        self.global_metawidget_index = ObjectIndexer.merge(self.mw_trees)

    # generate MetaWidgetTree from DOM.
    def _createMetaWidgets(self, dialog_dom):
        mw_tree = MetaWidgetTree()
        
        # create MetaWidget for "wx:Dialog"
        meta_widget = MetaWidgetEntry()
        meta_widget.setDOM(dialog_dom)
        mw_tree.setLink(None, meta_widget)
        
        # indexing "wx:Dialog" MetaWidget
        name = dialog_dom.getAttribute("name")
        mw_tree.setNameIndexForMetaWidget(meta_widget, name)

        # create sub MetaWidgets
        mw_tree_root = mw_tree.getRootMetaWidget()               
        self._aCreateMetaWidgets(dialog_dom, mw_tree_root, mw_tree)

        # if generation process is done successfully, append mw_tree to the MW list 
        self.mw_trees.append(mw_tree)

    def _aCreateMetaWidgets(self, parent_dom, parent_meta_widget, meta_widget_tree):        
        child_dom_nodes = parent_dom.childNodes
        
        for dom_node in child_dom_nodes:
            # create meta-widget tree
            if dom_node.nodeType != dom_node.ELEMENT_NODE: continue
            
            # when node is wx:dataProvider
            if dom_node.nodeName == "wx:dataProvider":
                data_provider = InternalDataProvider(dom_node)
                parent_meta_widget_node.setDataProvider(data_provider)
                continue
           
            meta_widget = MetaWidgetEntry()
            meta_widget.setDOM(dom_node)
            meta_widget_tree.setLink(parent_meta_widget, meta_widget)

            # for external data provider
            if dom_node.hasAttribute("dataProvider"):
                external_data_provider = ExternalDataProvider(dom_node)
                meta_widget.setDataProvider(external_data_provider)
            
            # add name of DOM object to the index for event binding.
            # indexing MetaWidget by name
            name = dom_node.getAttribute("name")
            meta_widget_tree.setNameIndexForMetaWidget(meta_widget, name)
       
            self._aCreateMetaWidgets(dom_node, meta_widget, meta_widget_tree)

    # generate real widgets by traversing MetaWidgetTree
    def createRealWidgets(self, name):
        BaseUIGenerator.createRealWidgets(self)
        
        mw_head = self.global_metawidget_index.find(name)
        
        if mw_head == None:
            raise "INVALID OR UNINITIALIZED DOM"
        
        top_widget = self.widget_generator.generate(mw_head)
        self._aCreateRealWidgets(mw_head)
        
        return top_widget